# icmp_probe.py
import asyncio
import time
from scapy.all import IP, ICMP, sr1

async def ping_host(ip):
    packet = IP(dst=ip) / ICMP()
    try:
        loop = asyncio.get_running_loop()
        response = await loop.run_in_executor(None, lambda: sr1(packet, timeout=0.5, verbose=0))

        if response and IP in response:
            ttl_value = response[IP].ttl  # 获取IP头部的TTL值
            return ip, ttl_value  # 返回IP地址和TTL值
    except Exception as e:
        print(f"Error pinging {ip}: {e}")
    return None, None  # 如果没有响应，返回None

async def scan_subnet(base_ip, subnet_start, subnet_end):
    tasks = []

    for i in range(subnet_start, subnet_end + 1):
        ip = f"{base_ip}.{i}"
        task = asyncio.create_task(ping_host(ip))
        tasks.append(task)

    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    # 过滤出存活的主机及其TTL值
    alive_ips_with_ttl = [(ip, ttl) for ip, ttl in results if isinstance(ip, str)]
    return alive_ips_with_ttl

async def scan_multiple_subnets(subnets):
    """
    扫描多个网段,subnets 是一个包含 (subnet_start, subnet_end, base_ip) 的列表。
    每个元组表示一个网段的起始、结束IP地址和基础IP地址。
    """
    tasks = []
    
    for subnet in subnets:
        subnet_start, subnet_end, base_ip = subnet
        task = asyncio.create_task(scan_subnet(subnet_start, subnet_end, base_ip))
        tasks.append(task)

    # 并发执行所有网段的扫描任务
    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    # 合并所有网段的扫描结果
    all_alive_ips_with_ttl = [item for sublist in results for item in sublist]
    return all_alive_ips_with_ttl

# if __name__ == "__main__":
#     # 定义要扫描的多个网段
#     subnets_to_scan = [
#         ("10.138.207", 1, 255),
#         ("221.183.101", 1, 255)
#     ]
#     start_time = time.time()
    
#     # 扫描多个网段
#     all_alive_ips_with_ttl = asyncio.run(scan_multiple_subnets(subnets_to_scan))
    
#     # 输出存活的主机及其TTL值
#     for ip, ttl in all_alive_ips_with_ttl:
#         print(f"Host {ip} is up with TTL: {ttl}")
    
#     end_time = time.time()
#     scan_time = end_time - start_time
#     print(f'Scan completed in {scan_time:.2f} seconds')


    # if __name__ == "__main__":
#     # 定义要扫描的多个网段
#     subnets_to_scan = [
#         ("221.183.101", 1, 255)
#     ]
    
#     start_time = time.time()
    
#     # 扫描多个网段
#     all_alive_ips_with_ttl = asyncio.run(scan_multiple_subnets(subnets_to_scan))
    
#     # 初始化两个列表来存储IP地址和TTL值
#     list_ip = []
#     list_ttl = []

#     # 输出存活的主机及其TTL值，并填充到两个列表中
#     for ip, ttl in all_alive_ips_with_ttl:
#         # print(f"Host {ip} is up with TTL: {ttl}")
#         list_ip.append(ip)
#         list_ttl.append(ttl)
    
#     end_time = time.time()
#     scan_time = end_time - start_time
#     print(f'Scan completed in {scan_time:.2f} seconds')

#     # 现在你可以使用 list_ip 和 list_ttl 进行进一步的操作
#     # 例如，打印它们以验证结果
#     print("List of IPs:", list_ip)
#     print("List of TTLs:", list_ttl)
